#ifndef SUPPORT_BITSETVECTOR_H
#define SUPPORT_BITSETVECTOR_H
//宏定义复位 将一个32位二进制数x的第n位（从右边算起，也就是bit0算第1位）清零
//宏GETBITSETS包含2个参数，x和n, 所以其模型为  CLR_BIT_N(x,n) ....
//对其某一位清零，我们可以将该位和0相与，其他位和1相与  x & ~(1<<((n)-1))
#define CLR_BIT_N(x,n) ((x) & ~(1<<((n)-1)))
#include <bitset>   //用于存储 2进制位
#include <vector>   //类似数组，但是能够自动扩展
#include <functional>
#include <iostream>

class BitSetVector {
    enum {BITSET_WORDSIZE = sizeof(long)*8 }; //枚举设定每个2进制单词的长度,比如是32位还是64位
//typedef 用来定义同义词, bitset 二进制容器内 数据结构定为  BITSET_WORDSIZE
    typedef std::bitset<BITSET_WORDSIZE> bitword;
    //reference 设为 bitword 实例里面的reference 的同义词
    typedef bitword::reference reference;
    class iterator;

    //vector容器内 的数据结构
    std::vector<bitword> bitsetVec;
    unsigned maxSize;
    private:
    //计算当前指令单词，是第几个
    //对寄存器直接位操作，对提高编译器性能至关重要
     //构造复杂2进制指令的方法
           /*
           bit3~bit9: 以bit0为基准构造结果为 0x3f
           bit23~bit25: 以bit0为基准构造结果为 0x07
           开始移位相或: 
           0x0380003f=(0x3f<<3)|(0x07<<23)
           开发编译器必须用到位运算，为了榨干芯片的性能
           程序语言控制硬件就是通过位运算控制寄存器，对寄存器进行读改写操作；
           对寄存器特定位的操作分为：清零（用&位与），置1（用|位或），和取反(用～位异或^)
           32位2进制对应32位并行信号电路寄存器
         
           */
          /*
            位运算对寄存器直接操作，对提高编译器性能至关重要
            首先要学会配置寄存器操作：
            构造复杂2进制数指令 32位，比如构造bit3-bit7为1， bit23-bit25为1，其余都为0的2进制数指令
             方法：移位相或
            移位操作的规律: 
            左移位就是将一个操作数的各个2进制位全部左移若干位，左边移出去的2进制位丢弃，右边空出来的补零
                          每一次左移位，得到的结果是原操作数的一倍(x<<n = x*2^n)
            
                          每一次右移位，得到的结果是原操作数的一半，小数位忽略  (x>>n = x/2^n)
           */
       static unsigned NumWords(unsigned Size){
           int a = (0x3f<<3)|(0x07<<23); //0x0380003f
           int b = ~0; //0按位取反，=1
           int c =  0b0011   &  0b0101; // 与运算=0b0001 =1
           int d =  0b0011 | 0b0101; //或运算=0b0111 = 7
           int e =  ~0b1010; //0b0101 //按位取反= 5  遇0变1， 遇1变0 
           int f =  0b0011 ^ 0b0101; //0b0110 //位异或 两个位相等结果为0，不等则结果为1
           return (Size+BITSET_WORDSIZE-1)/BITSET_WORDSIZE;
       }
       //求余计算最后一个程序单词，占据内存大小
       static unsigned LastWordSize(unsigned Size) { return Size % BITSET_WORDSIZE; }
       //清空程序单词中没有使用的字节所占的内存
       void ClearUnusedBits(){
           //通过移位运算符，将(BITSET_WORDSIZE - LastWordSize())的结果，置为高位
           //每进行一次左移位，得到的结果是原操作数的一倍（x<<n = x*2^n)
           unsigned long usedBits = (1U << LastWordSize(size()))-1;
           //和bitword(usedBits)进行 位与操作(&=)  并将结果赋予bitsetVec.back()返回值 
           bitsetVec.back() &= bitword(usedBits);
          
       }
       
       /*
       编译器底层对芯片操作，离不开指针应用，对各种电脑驱动的操作更是离不开指针
       */
       const bitword& getWord(unsigned i) const {return bitsetVec[i];}
             bitword& getWord(unsigned i)       {return bitsetVec[i];}

       
    public:

};